﻿using System;
using System.Runtime.Caching;

namespace NovelDownload.Common
{
    /// <summary>
    /// 内存缓存帮助类
    /// </summary>
    public class MemoryCacheHelper
    {
        private static readonly Object _locker = new object();

        /// <summary>
        /// 根据key获取或设置缓存
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key">key</param>
        /// <param name="value">value</param>
        /// <param name="expiration">过期时间</param>
        /// <returns></returns>
        public static T GetOrSetCacheItem<T>(string key, T value, TimeSpan? expiration = null)
        {
            if (string.IsNullOrWhiteSpace(key)) throw new ArgumentException("cache key");
            if (value == null) throw new ArgumentNullException("cachePopulate");
            if (expiration == null) throw new ArgumentException("expiration must be provided");

            if (MemoryCache.Default[key] == null)
            {
                lock (_locker)
                {
                    if (MemoryCache.Default[key] == null)
                    {
                        var item = new CacheItem(key, value);
                        var policy = CreatePolicy(expiration);

                        MemoryCache.Default.Add(item, policy);
                    }
                }
            }

            return (T)MemoryCache.Default[key];
        }

        /// <summary>
        /// 获取缓存
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key">key</param>
        /// <returns></returns>
        public static T GetCacheItem<T>(string key)
        {
            if (string.IsNullOrWhiteSpace(key)) throw new ArgumentException("cache key");

            return (T)MemoryCache.Default[key];
        }

        /// <summary>
        /// 设置缓存
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <param name="expiration"></param>

        public static void SetCacheItem<T>(string key, T value, TimeSpan? expiration = null)
        {
            if (string.IsNullOrWhiteSpace(key)) throw new ArgumentException("cache key");
            if (value == null) throw new ArgumentNullException("cachePopulate");
            if (expiration == null) throw new ArgumentException("expiration must be provided");

            lock (_locker)
            {
                var item = new CacheItem(key, value);
                var policy = CreatePolicy(expiration);

                MemoryCache.Default.Add(item, policy);
            }
        }


        /// <summary>
        /// 移除缓存
        /// </summary>
        /// <param name="key">key</param>
        public static void RemoveCacheItem(string key)
        {
            MemoryCache.Default.Remove(key);
        }


        /// <summary>
        /// 设置代理
        /// </summary>
        /// <param name="slidingExpiration"></param>
        /// <returns></returns>
        private static CacheItemPolicy CreatePolicy(TimeSpan? expiration)
        {
            var policy = new CacheItemPolicy();

            if (expiration.HasValue)
            {
                policy.SlidingExpiration = expiration.Value;
            }

            policy.Priority = CacheItemPriority.Default;

            return policy;
        }
    }
}
